/**
 * @file rtk_ipc.h
 * @author LokLiang (lokliang@163.com)
 * @brief
 * @version 0.1
 * @date 2023-05-01
 *
 * @copyright Copyright (c) 2023
 *
 */

#ifndef __RTK_IPC_H__
#define __RTK_IPC_H__

#include "rtk_def.h"
#include "rtk_work.h"
#include "rtk_semaphore.h"

#ifdef __cplusplus
extern "C"
{
#endif /* #ifdef __cplusplus */

typedef struct
{
    rtk_hdl_t hdl;
} rtk_fifo_t;

rtk_err_t rtk_fifo_q_create(rtk_fifo_t *fifo_handle, const char *name, rtk_sem_type type); // 创建一个FIFO对象
rtk_err_t rtk_fifo_q_delete(rtk_fifo_t *fifo_handle);                                      // 删除一个FIFO的对象
rtk_err_t rtk_fifo_q_clr(rtk_fifo_t *fifo_handle);                                         // 清除FIFO内的所有数据

void rtk_fifo_q_regist(rtk_fifo_t *fifo_handle, rtk_work_t *work_handle, rtk_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
void rtk_fifo_q_unregist(rtk_fifo_t *fifo_handle);                                                // 取消注册任务

void     *rtk_fifo_alloc(size_t size, rtk_tick_t wait_ticks);     // 申请可用于FIFO的数据结构
rtk_err_t rtk_fifo_put(rtk_fifo_t *fifo_handle, void *fifo_data); // 把数据结构压入到FIFO中

void     *rtk_fifo_take(rtk_fifo_t *fifo_handle, rtk_tick_t wait_ticks); // 从FIFO中弹出最先压入的数据
rtk_err_t rtk_fifo_free(void *fifo_data);                                // 释放由 rtk_fifo_alloc() 申请的数据结构

void *rtk_fifo_peek_head(rtk_fifo_t *fifo_handle); // 查询FIFO中头部的数据地址
void *rtk_fifo_peek_tail(rtk_fifo_t *fifo_handle); // 查询FIFO中尾部的数据地址

bool rtk_fifo_q_is_valid(rtk_fifo_t *fifo_handle); // 获取有效状态

typedef struct
{
    rtk_hdl_t hdl;
} rtk_queue_t;

rtk_err_t rtk_queue_create(rtk_queue_t *queue_handle,
                           const char *name,
                           rtk_sem_type type,
                           size_t queue_length,
                           size_t item_size);
rtk_err_t rtk_queue_delete(rtk_queue_t *queue_handle); // 删除一个队列的对象
rtk_err_t rtk_queue_clr(rtk_queue_t *queue_handle);    // 清除队列内的所有数据

void rtk_queue_regist(rtk_queue_t *queue_handle, rtk_work_t *work_handle, rtk_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
void rtk_queue_unregist(rtk_queue_t *queue_handle);                                                // 取消注册任务

rtk_err_t rtk_queue_recv(rtk_queue_t *queue_handle, void *dst, rtk_tick_t wait_ticks);       // 接收并复制数据
rtk_err_t rtk_queue_send(rtk_queue_t *queue_handle, const void *src, rtk_tick_t wait_ticks); // 复制数据并发送

void     *rtk_queue_alloc(rtk_queue_t *queue_handle, rtk_tick_t wait_ticks); // 申请可用于队列的数据结构
rtk_err_t rtk_queue_put(void *queue_data);                                   // 把数据压入到队列中
void     *rtk_queue_take(rtk_queue_t *queue_handle, rtk_tick_t wait_ticks);  // 从队列中弹出最先压入的数据
rtk_err_t rtk_queue_free(void *queue_data);                                  // 释放由 rtk_queue_alloc() 申请的数据结构

void *rtk_queue_peek_head(rtk_queue_t *queue_handle); // 查询队列中头部的数据地址
void *rtk_queue_peek_tail(rtk_queue_t *queue_handle); // 查询队列中尾部的数据地址

size_t rtk_queue_get_item_size(rtk_queue_t *queue_handle); //读回 k_queue_create() 中设置的 item_size 的值

bool rtk_queue_is_valid(rtk_queue_t *queue_handle); // 获取有效状态

typedef struct
{
    rtk_hdl_t hdl;
} rtk_pipe_t;

rtk_err_t rtk_pipe_create(rtk_pipe_t *pipe_handle, const char *name, size_t pipe_size, rtk_sem_type type); // 创一个管道对象
rtk_err_t rtk_pipe_delete(rtk_pipe_t *pipe_handle);                                                        // 删除一个管道对象
rtk_err_t rtk_pipe_clr(rtk_pipe_t *pipe_handle);                                                           // 清空管道的数据

void rtk_pipe_regist(rtk_pipe_t *pipe_handle, rtk_work_t *work_handle, rtk_tick_t delay_ticks); // 注册当队列非空时被唤醒的任务
void rtk_pipe_unregist(rtk_pipe_t *pipe_handle);                                                // 取消注册任务

size_t rtk_pipe_poll_write(rtk_pipe_t *pipe_handle, uint8_t data);                 // 写一个字节到缓存中（写入缓存），返回实际复制成功的字节数
size_t rtk_pipe_fifo_fill(rtk_pipe_t *pipe_handle, const void *data, size_t size); // 把内存数据复制到缓存中（写入缓存），返回实际复制成功的字节数
size_t rtk_pipe_poll_read(rtk_pipe_t *pipe_handle, uint8_t *data);                 // 从缓存复制一个字节到指定地址中，返回 0 表示缓存空
size_t rtk_pipe_fifo_read(rtk_pipe_t *pipe_handle, void *data, size_t size);       // 从管道中复制数据到内存（从缓存读取），返回实际复制成功的字节数。注：参数 data 值可以为 NULL，此时不复制数据，只释放相应的数据量

bool   rtk_pipe_is_ne(rtk_pipe_t *pipe_handle);          // 获取管道非空, true 有数据
size_t rtk_pipe_get_valid_size(rtk_pipe_t *pipe_handle); // 获取管道的数据大小（字节数）
size_t rtk_pipe_get_empty_size(rtk_pipe_t *pipe_handle); // 获取管道的剩余空间（字节数）

void rtk_pipe_peek_valid(rtk_pipe_t *pipe_handle, void **dst_base, size_t *dst_size); // 获取当前已写入的连续的内存信息
void rtk_pipe_peek_empty(rtk_pipe_t *pipe_handle, void **dst_base, size_t *dst_size); // 获取当前空闲的连续的内存信息

bool rtk_pipe_is_valid(rtk_pipe_t *pipe_handle); // 获取有效状态

#ifdef __cplusplus
} /* extern "C" */
#endif /* #ifdef __cplusplus */

#endif
